home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac-Source 1994 July
/
Mac-Source_July_1994.iso
/
C and C++
/
Commun⁄Network
/
CITADEL BBS 'C' SRC
/
NETCALL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1987-01-14
|
17KB
|
603 lines
/************************************************************************/
/* netcall.c */
/* */
/* Networking call functions. */
/************************************************************************/
/************************************************************************/
/* history */
/* */
/* 86Aug20 HAW History not maintained due to space problems. */
/************************************************************************/
#include "ctdl.h"
/************************************************************************/
/* contents */
/* */
/************************************************************************/
/************************************************************************/
/* External variable declarations in NET.C */
/************************************************************************/
char inReceive;
extern FILE *netMisc;
extern FILE *netLog;
extern ulong roomHiMsgs[MAXROOMS];
extern unsigned char sectBuf[SECTSIZE + 5];
extern int counter;
extern int callSlot;
extern int FinHour, FinMinute;
extern label normed, callerName, callerId;
char checkNegMail;
extern char processMail;
extern int noKill, errCount;
char normId(), getNetMessage();
char callOut();
unsigned char inp();
extern struct nodeRoomsTab *sharedRooms;
extern struct config cfg; /* Lots an lots of variables */
extern struct logBuffer logBuf; /* Person buffer */
extern struct aRoom roomBuf; /* Room buffer */
extern struct rTable roomTab[];
extern struct msgB msgBuf,tempMess;
extern struct netBuffer netBuf;
extern struct netTable *netTab;
extern FILE *upfd;
extern int thisNet;
extern char onConsole;
extern char loggedIn; /* Is we logged in? */
extern char outFlag; /* Output flag */
extern char haveCarrier; /* Do we still got carrier? */
extern unsigned char modStat; /* Needed so we don't die */
extern char usingWCprotocol;/* WC flag */
extern char WCError;
char *chMailTemplate = "%c:chkMail.$$$";
/************************************************************************/
/* External function definitions for NET.C */
/************************************************************************/
FILE *safeopen();
FILE *fopen();
char *realloc();
char *index();
long getNumber();
/************************************************************************/
/* caller() we've called and got carrier, so let's goferit */
/************************************************************************/
caller()
{
inReceive = FALSE;
processMail = FALSE;
checkNegMail = FALSE;
splitF(netLog, "Have Carrier\n");
caller_stabilize();
if (!haveCarrier) return ; /* Abort */
splitF(netLog, "Have stabilized call with receiver\n");
sendId();
if (!haveCarrier) return ; /* Abort */
sendStuff(FALSE);
while (gotCarrier()) ;
doResults();
splitF(netLog, "Call to %s finished successfully\n\n", netBuf.netName);
modStat = haveCarrier = FALSE;
}
/************************************************************************/
/* sendStuff() assume role of sender */
/************************************************************************/
sendStuff(reversed)
char reversed;
{
if (callSlot != ERROR) {
if (netBuf.nbflags.normal_mail) {
sendMail();
if (!haveCarrier) return ; /* Abort */
checkMail();
}
if (!haveCarrier) return ; /* Abort */
if (netBuf.nbflags.room_files)
askFiles();
if (!haveCarrier) return ; /* Abort */
sendSharedRooms();
if (!haveCarrier) return ; /* Abort */
roleReversal(reversed);
if (!haveCarrier) return ; /* Abort */
}
sendHangUp();
}
/************************************************************************/
/* roleReversal() hokay, into drag */
/************************************************************************/
roleReversal(reversed)
{
struct cmd_data cmds;
if (reversed) return ;
if (!netBuf.nbflags.local) return ;
splitF(netLog, "Reversing roles\n");
zero_struct(cmds);
cmds.command = ROLE_REVERSAL;
if (!sendNetCommand(&cmds, "role reversal"))
return;
rcvStuff(TRUE);
reply(GOOD, "");
}
/************************************************************************/
/* caller_stabilize() Tries to stabilize the call -- */
/* baud is already set */
/************************************************************************/
caller_stabilize()
{
int Time, i, j;
int x1, x2, x3;
pause(200); /* Pause a full 2 seconds */
while (MIReady()) inp(); /* Clear garbage */
for (Time = 0; Time < 20 && gotCarrier(); Time++) {
if (cfg.debug) splitF(netLog, ".");
outMod(7);
pause(10);
outMod(13);
pause(10);
outMod(69);
for (j = 0; j < INTERVALS && !MIReady(); j++)
for (i = 0; i < 250 && !MIReady(); i++)
shortPause();
if (MIReady()) {
x1 = receive(2);
x2 = receive(2);
if (x2 != ERROR) x3 = receive(2);
if (x1 == 248 &&
x2 == 242 &&
x3 == 186) {
outMod(ACK);
if (cfg.debug) splitF(netLog, "ACKing, Call stabilized\n");
return;
}
else if (cfg.debug) splitF(netLog, "%d %d %d\n", x1, x2, x3);
}
}
splitF(netLog, "Call not stabilized\n");
modStat = haveCarrier = FALSE;
interpret(cfg.pHangUp);
}
/************************************************************************/
/* sendId() Sends ID to the receiver */
/************************************************************************/
sendId()
{
char *reason;
char message[40];
if (!gotCarrier()) return modStat = haveCarrier = FALSE;
if (!doWC(STARTUP)) {
no_good("Couldn't transfer ID to %s!", TRUE);
modStat = haveCarrier = FALSE;
interpret(cfg.pHangUp);
return;
}
mWCprintf("%s", cfg.codeBuf + cfg.nodeId );
mWCprintf("%s", cfg.codeBuf + cfg.nodeName);
if (WCError) {
if (!gotCarrier()) {
modStat = haveCarrier = FALSE;
reason = "carrier loss";
}
else reason = "WC abort: 10 errors or CANCEL";
doWC(FINISH);
strCpy(message, "Couldn't transfer ID to %s! ");
strCat(message, reason);
no_good(message, TRUE);
return;
}
doWC(FINISH);
}
/************************************************************************/
/* sendMail() send normal mail to receiver */
/************************************************************************/
sendMail()
{
struct cmd_data cmds;
int i, nor_mail;
char *reason, message[50];
if (!gotCarrier()) return modStat = haveCarrier = FALSE;
splitF(netLog, "Sending normal mail\n");
zero_struct(cmds);
cmds.command = NORMAL_MAIL;
if (!sendNetCommand(&cmds, "normal mail"))
return;
if (!doWC(STARTUP)) {
no_good("Couldn't start Mail transfer to %s!", TRUE);
modStat = haveCarrier = FALSE;
interpret(cfg.pHangUp);
return;
}
nor_mail = s_m_n(); /* Send normal mail */
if (WCError) {
if (!gotCarrier()) {
modStat = haveCarrier = FALSE;
reason = "carrier loss";
}
else reason = "WC abort: 10 errors or CANCEL";
doWC(FINISH);
strCpy(message, "Couldn't transfer ID to %s! ");
strCat(message, reason);
no_good(message, TRUE);
return;
}
else {
splitF(netLog, "\nSuccessful transfer of %d messages\n", nor_mail);
netBuf.nbflags.normal_mail = FALSE;
}
doWC(FINISH);
}
/************************************************************************/
/* checkMail() negative acknowledgement on netMail> */
/************************************************************************/
checkMail()
{
struct cmd_data cmds;
int i, nor_mail, putFLChar();
char *reason, message[50];
if (!gotCarrier()) return modStat = haveCarrier = FALSE;
splitF(netLog, "Asking for check on normal mail\n");
zero_struct(cmds);
cmds.command = CHECK_MAIL;
if (!sendNetCommand(&cmds, "check mail"))
return;
sPrintf(message, chMailTemplate, cfg.netDisk + 'A');
upfd = safeopen(message, "wb");
readFile(putFLChar);
fclose(upfd);
checkNegMail = TRUE; /* Call readNegMail() later */
}
/************************************************************************/
/* readNegMail() reads and processes negative acks */
/************************************************************************/
readNegMail()
{
char message[30];
label author, target, context;
int whatLog;
struct logBuffer lBuf;
int sigChar;
sPrintf(message, chMailTemplate, cfg.netDisk + 'A');
if ((netMisc = safeopen(message, "rb")) == NULL) {
no_good("Couldn't open negative ack file from %s.", TRUE);
return ;
}
getRoom(MAILROOM);
sigChar = getc(netMisc);
while (sigChar != NO_ERROR && sigChar != EOF && sigChar != EOF) {
zero_struct(msgBuf);
strCpy(msgBuf.mbauth, "Citadel");
getNetStr(author);
getNetStr(target);
getNetStr(context);
switch (sigChar) {
case NO_RECIPIENT:
strCpy(msgBuf.mbto, author);
if (strLen(author) > 0 && getRecipient(&lBuf, &whatLog)) {
sPrintf(msgBuf.mbtext,
"Your netMail to '%s' (%s) failed because there is no such recipient on %s.",
target, context, callerName);
if (putMessage()) noteMessage(&lBuf, whatLog);
break;
}
case UNKNOWN:
zero_struct(msgBuf);
sPrintf(msgBuf.mbtext,
"Unknown problems with netMail: author=-%s-,target=-%s-,context=-%s-",
author, target, context);
aideMessage(FALSE);
break;
case BAD_FORM:
sPrintf(msgBuf.mbtext, "Bad netMail sent to %s.", callerName);
aideMessage(FALSE);
break;
default:
sPrintf(msgBuf.mbtext, "Bad sigChar=%d.", sigChar);
aideMessage(FALSE);
break;
}
sigChar = getc(netMisc);
}
fclose(netMisc);
unlink(message);
}
/************************************************************************/
/* sendSharedRooms() Sends all shared rooms to receiver */
/************************************************************************/
sendSharedRooms()
{
struct cmd_data cmds;
int msgRover;
char mess[140];
extern char *R_SH_MARK;
int rover;
for (rover = 0; rover < SHARED_ROOMS; rover++) {
if (!gotCarrier()) {
modStat = haveCarrier = FALSE;
return;
}
if (isSharedRoom(thisNet, rover) && roomValidate(rover)) {
if (roomHiMsgs[netRoomSlot(rover)] >
netBuf.netRooms[rover].lastMess) {
getRoom(netRoomSlot(rover));
zero_struct(cmds);
cmds.command = NET_ROOM;
strCpy(cmds.fields[0], roomBuf.rbname);
splitF(netLog, "Sending %s\n", roomBuf.rbname);
if (sendNetCommand(&cmds, "shared rooms")) {
if (!doWC(STARTUP)) {
no_good("Couldn't start WC for room sharing: %s",
FALSE);
continue;
}
usingWCprotocol = WC_NETWORK;
for (msgRover = 0; msgRover < MSGSPERRM; msgRover++) {
if (netBuf.netRooms[rover].lastMess <
roomBuf.msg[msgRover].rbmsgNo) {
if (findMessage(roomBuf.msg[msgRover].rbmsgLoc,
roomBuf.msg[msgRover].rbmsgNo))
if (strCmpU(msgBuf.mbaddr, R_SH_MARK) ==
SAMESTRING)
printMessage(roomBuf.msg[msgRover].rbmsgLoc,
roomBuf.msg[msgRover].rbmsgNo);
}
}
doWC(FINISH);
usingWCprotocol = WC_NONE;
netBuf.netRooms[rover].lastMess = roomHiMsgs[netRoomSlot(rover)];
sharedRooms[thisNet].rooms[rover].lastMess =
roomHiMsgs[netRoomSlot(rover)];
}
else {
strCpy(mess, "%s reports: ");
strCat(mess, sectBuf + 1);
no_good(mess, FALSE);
resetNetRoomFlag(rover);
}
}
}
else resetNetRoomFlag(rover);
}
}
/************************************************************************/
/* askFiles() ask for file(s) from caller */
/************************************************************************/
askFiles()
{
label data;
int putFLChar(), i;
char mess[130], *cd, *gcdir();
char ambiguous;
FILE *temp;
struct cmd_data cmds;
struct fl_req file_data;
if (!gotCarrier()) return modStat = haveCarrier = FALSE;
sPrintf(data, "a:%d.rfl", thisNet);
data[0] = cfg.netDisk + 'a';
temp = safeopen(data, "rb");
if (temp == NULL) {
no_good("Couldn't open room request file for %s", FALSE);
netBuf.nbflags.room_files = FALSE;
}
else {
splitF(netLog, "Asking for files\n");
while (fread(&file_data, sizeof (file_data), 1, temp) == 1 &&
gotCarrier()) {
setSpace(toUpper(file_data.drive) - 'A', "");
cd = gcdir("");
if (chdir(file_data.path) != EOF) {
zero_struct(cmds);
ambiguous = !(index(file_data.roomfile, '*') == NULL &&
index(file_data.roomfile, '?') == NULL);
cmds.command = (!ambiguous) ? R_FILE_REQ : A_FILE_REQ;
strCpy(cmds.fields[0], file_data.room);
strCpy(cmds.fields[1], file_data.roomfile);
splitF(netLog, "%s in %s\n", file_data.roomfile, file_data.room);
if (!sendNetCommand(&cmds,
(!ambiguous) ? "single file request" :
"multiple file request")) {
strCpy(mess, "%s reports: ");
strCat(mess, sectBuf + 1);
no_good(mess, FALSE);
}
else {
if (ambiguous) multiReceive(file_data.path);
else {
upfd = safeopen(file_data.filename, "wb");
readFile(putFLChar);
fclose(upfd);
sPrintf(msgBuf.mbtext, "The file '%s' received from %s.",
file_data.filename, netBuf.netName);
aideMessage(FALSE);
}
}
chdir(cd);
free(cd);
}
setSpace(cfg.homeDisk, "");
}
fclose(temp);
if (gotCarrier()) {
unlink(data);
netBuf.nbflags.room_files = FALSE;
}
else haveCarrier = modStat = FALSE;
}
}
/************************************************************************/
/* multiReceive() Receive multiple files */
/************************************************************************/
multiReceive(subdir)
char *subdir;
{
int increment(), putFLChar();
char first = 1;
char *end;
sPrintf(msgBuf.mbtext, "Following files received from %s: ",netBuf.netName);
do {
counter = 0;
readFile(increment);
if (!gotCarrier()) return;
if (sectBuf[0] == 0) { /* Last file name */
end = msgBuf.mbtext + strLen(msgBuf.mbtext);
sPrintf(end, " (stored in directory %s).", subdir);
aideMessage(FALSE);
return;
}
if (!first)
strCat(msgBuf.mbtext, ", ");
else
first = FALSE;
strCat(msgBuf.mbtext, sectBuf);
upfd = safeopen(sectBuf, "wb");
readFile(putFLChar);
fclose(upfd);
} while (1);
}
/************************************************************************/
/* sendNetCommand() Sends a command to the receiver */
/************************************************************************/
sendNetCommand(cmds, error)
struct cmd_data *cmds;
char *error;
{
int count, increment();
char errMsg[100];
if (!doWC(STARTUP)) {
sPrintf(errMsg, "Link failure for %s (system: %%s).", error);
no_good(errMsg, TRUE);
modStat = haveCarrier = FALSE;
interpret(cfg.pHangUp);
return;
}
sendWCChar(cmds->command);
for (count = 0; count < 4; count++)
if (cmds->fields[count][0])
mWCprintf("%s", cmds->fields[count]);
sendWCChar(0);
doWC(FINISH);
counter = 0;
if (cmds->command == HANGUP && !inReceive) return TRUE;
readFile(increment);
if (sectBuf[0] == BAD) return FALSE;
return TRUE;
}
/************************************************************************/
/* sendHangUp() Send hangup command to receiver */
/************************************************************************/
sendHangUp()
{
struct cmd_data cmds;
int i;
if (!gotCarrier()) return modStat = haveCarrier = FALSE;
zero_struct(cmds);
cmds.command = HANGUP;
sendNetCommand(&cmds, "HANGUP");
}
/************************************************************************/
/* no_good() does error messages */
/************************************************************************/
no_good(str, hup)
char *str;
char hup;
{
sPrintf(msgBuf.mbtext, str, netBuf.netName);
if (hup) {
interpret(cfg.pHangUp);
modStat = haveCarrier = FALSE;
}
aideMessage(FALSE);
}
/************************************************************************/
/* s_m_n() Send mail normal (non-route mail) */
/************************************************************************/
s_m_n()
{
FILE *ptrs;
char c;
label fn;
ulong id;
int val, messCount = 0;
struct netMLstruct buf;
unsigned location;
sPrintf(fn, "a:%d.ml", thisNet);
fn[0] = cfg.netDisk + 'a';
if ((ptrs = safeopen(fn, "rb")) == NULL) {
sPrintf(msgBuf.mbtext, "No mail file to send to %s?", netBuf.netName);
aideMessage(FALSE);
return 0;
}
usingWCprotocol = WC_NETWORK;
while (getMLNet(ptrs, buf)) {
printMessage(buf.ML_loc, buf.ML_id);
messCount++;
}
usingWCprotocol = WC_NONE;
fclose(ptrs);
if (!WCError) {
unlink(fn);
return messCount;
}
splitF(netLog, "\nUnsuccessful transfer of normal mail\n");
return 0;
}